package org.infodavid.common.services.security;

import java.util.Collection;

import javax.persistence.PersistenceException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.infodavid.common.impl.services.validators.DefaultAccessControlListValidator;
import org.infodavid.common.model.IUser;
import org.infodavid.common.model.IUserGroup;
import org.infodavid.common.model.ModelFactory;
import org.infodavid.common.model.criteria.IAccessControlListCriteria;
import org.infodavid.common.model.security.IAccessControlList;
import org.infodavid.common.reflect.InstantiationHelper;
import org.infodavid.common.services.AbstractEntityService;
import org.infodavid.common.services.IApplicationContext;
import org.infodavid.common.services.exceptions.ServiceException;

/**
 * The Class AccessControlService.
 */
public abstract class AccessControlService extends
    AbstractEntityService<IAccessControlList,IAccessControlList,IAccessControlListCriteria> {

	/** The Constant log. */
	private static final Log LOGGER = LogFactory.getLog(AccessControlService.class);

	/** The singleton. */
	private static final AccessControlService SINGLETON;

	static {
		try {
			SINGLETON = InstantiationHelper.getInstance().newInstance(AccessControlService.class);
		}
		catch (final Exception e) {
			LOGGER.fatal("Can not instantiate the " + AccessControlService.class.getName(), e);

			throw new Error(e);
		}
	}

	/**
	 * returns the singleton.
	 * @return <code>UserService</code>
	 */
	public static AccessControlService getInstance() {
		return SINGLETON;
	}

	/**
	 * Instantiates a new service.
	 */
	protected AccessControlService() {
		super(IAccessControlList.class, new DefaultAccessControlListValidator(), ModelFactory
		    .getInstance().getBuilder(IAccessControlList.class));
	}

	/**
	 * Find the entity by the name.
	 * @param context the context
	 * @param value the name
	 * @return the entity
	 * @throws ServiceException the service exception
	 * @throws PersistenceException the persistence exception
	 */
	public abstract IAccessControlList findByName(IApplicationContext context, String value)
	    throws ServiceException, PersistenceException;

	/**
	 * Check if the given groups are allowed.
	 * @param groups the groups
	 * @param feature the feature
	 * @param context the context
	 * @return true, if allow
	 */
	public abstract boolean isAllowed(IApplicationContext context, Collection<IUserGroup> groups,
	    String feature);

	/**
	 * Check if the user is allowed.
	 * @param user the user
	 * @param feature the feature
	 * @param context the context
	 * @return true, if allow
	 */
	public abstract boolean isAllowed(IApplicationContext context, IUser user, String feature);

	/**
	 * Check if the group is allowed.
	 * @param group the group
	 * @param feature the feature
	 * @param context the context
	 * @return true, if allow
	 */
	public abstract boolean isAllowed(IApplicationContext context, IUserGroup group, String feature);
}
